var db = connect('demo08'); //链接数据库

// 第09节：修改：状态返回与安全
  /* 
    在操作数据库时，对数据的修改是需要有足够的安全措施的，其实在实际工作中，我们用db.collections.update的时候不多，
    在修改时我们都会用findAndModify，它可以给我们返回来一些必要的参数，让我们对修改多了很多控制力，控制力的加强也就
    是对安全的强化能力加强了。
  */

  // 应答式写入：
  /* 
    在动手学习代码之前，我们先来了解一个概念：应答式写入。在以前的文章中，我们的操作都是非应答式写入，就是在操作完数据
    库后，它并没有给我们任何的回应和返回值，而是我们自己安慰自己写了一句话（print(‘[update]:The data was updated su
    ccessfully’);）。这在工作中是不允许的，因为根本不能提现我们修改的结果。


    应答式写入就会给我们直接返回结果（报表），结果里边的包含项会很多，这样我们就可以很好的进行程序的控制和安全机制的处理。
    有点像前端调用后端接口，无论作什么，后端都要给我一些状态字一样。
  */

// db.runCommand():
  /* 
    它是数据库运行命令的执行器，执行命令首选就要使用它，因为它在Shell和驱动程序间提供了一致的接口。（几乎操作数据库的所有
    操作，都可以使用runCommand来执行）现在我们试着用runCommand来修改数据库，看看结果和直接用db.collections.update有什
    么不同。

  */

// db.workmate.update({ sex: 1 }, { $set: { money: 1000 } }, false, true);  //false：第一句末尾的false是upsert的简写，代表没有此条数据时不增加;  true：true是multi的简写，代表修改所有，这两个我们在前边课程已经学过。
// var resultMessage = db.runCommand({ getLastError: 1 });  //getLastError:1 :表示返回功能错误，这里的参数很多，如果有兴趣请自行查找学习，这里不作过多介绍。
// printjson(resultMessage); //printjson：表示以json对象的格式输出到控制台。

  /* 
    执行后,db.workmate.find()查了结果  疑问: 明明upsert为false,而且sex为1的,都没有money这个属性,为什么最后还加成功上去,不是upsert为false就不加吗
    { "_id" : ObjectId("5b8a9fc8b98908f8cdac7474"), "name" : "JSPang", "age" : 33, "sex" : 1, "job" : "前端", "skill" : { "skillOne" : "HTML+CSS", "SkillTwo" : "JavaScript", "SkillThree" : "PHP" }, "regeditTime" : ISODate("2018-09-01T14:18:48.663Z"), "money" : 1000 }
    { "_id" : ObjectId("5b8a9fc8b98908f8cdac7475"), "name" : "ShengLei", "age" : 30, "sex" : 1, "job" : "JAVA后端", "skill" : { "skillOne" : "HTML+CSS", "SkillTwo" : "J2EE", "SkillThree" : "PPT" }, "regeditTime" : ISODate("2018-09-01T14:18:48.663Z"), "money" : 1000 }
    { "_id" : ObjectId("5b8a9fc8b98908f8cdac7476"), "name" : "MinJie", "age" : 20, "sex" : 0, "job" : "UI设计", "skill" : { "skillOne" : "PhotoShop", "SkillTwo" : "UI", "SkillThree" : "Word+Excel+PPT", "SkillFour" : [ "draw" ] }, "regeditTime" : ISODate("2018-09-01T14:18:48.663Z") }
    { "_id" : ObjectId("5b8aa095283e6b5608563aae"), "name" : "xiaoWang", "age" : 20, "aihao" : [ "draw", null, "Code", "Sing", "Dance" ] }
  */

  /* 
    上边的代码，我们修改了所有男士的数据，每个人增加了1000元钱(money)，然后用db.runCommand()执行，可以看到执行结果在控制
    台返回了。
  */
  /* 
    connecting to: mongodb://127.0.0.1:27017/demo08
    MongoDB server version: 3.4.0
    {
            "connectionId" : 17,
            "updatedExisting" : true,
            "n" : 2,
            "syncMillis" : 0,
            "writtenTo" : null,
            "err" : null,
            "ok" : 1
    }
    true
  */

  /* 
    false：第一句末尾的false是upsert的简写，代表没有此条数据时不增加;
    true：true是multi的简写，代表修改所有，这两个我们在前边课程已经学过。
    getLastError:1 :表示返回功能错误，这里的参数很多，如果有兴趣请自行查找学习，这里不作过多介绍。
    printjson：表示以json对象的格式输出到控制台。
  */

  // db.listCommands( ):查看所有的Commad命令，内容很多，本套课程只讲解工作中经常使用的内容。
    // 比如我们要查看是否和数据库链接成功了，就可以使用Command命令。
    // db.runCommand({ ping: 1 })
    // 返回ok：1就代表链接正常。


// findAndModify:
    // 从名字上就可以看出，findAndModify是查找并修改的意思。配置它可以在修改后给我们返回修改的结果。
    // 我们先看下面的代码：
var myModify={
  findAndModify: 'workmate',  //集合
  query: { name: 'xiaoWang' },  //需要查询的条件/文档
  update:{$set:{age:56}},
  new: true  //更新完成，需要查看结果，如果为false不进行查看结果
}
var resultMessage = db.runCommand(myModify);
printjson(resultMessage)

  // 执行之后放回的结果
  /* 
    {
      "lastErrorObject" : {
              "updatedExisting" : true,
              "n" : 1
      },
      "value" : {
              "_id" : ObjectId("5b8aa095283e6b5608563aae"),
              "name" : "xiaoWang",
              "age" : 56,
              "aihao" : [
                      "draw",
                      null,
                      "Code",
                      "Sing",
                      "Dance"
              ]
      },
      "ok" : 1
    }
    true
  */ 

  // findAndModify的性能是没有直接使用db.collections.update的性能好，但是在实际工作中都是使用它，毕竟要商用的程序安全性还是比较重要的。

  // findAndModify属性值：
  /* 
    query：需要查询的条件/文档
    sort: 进行排序
    remove：[boolean]是否删除查找到的文档，值填写true，可以删除。
    new:[boolean]返回更新前的文档还是更新后的文档。
    fields：需要返回的字段
    upsert：没有这个值是否增加。
  */

  // 总结：这节课讲了一些跟安全有关的操作，但这不是全部，我们随着课程的深入还会继续学习更多的知识。工作中尽量使用findAndModify来进行更新数据，这样会更安全和直观，这点性能的损失是值得的。













